package com.yvon.maple.service.base.controller;

import cn.hutool.core.collection.CollUtil;
import com.yvon.boot.common.result.ResponseData;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 进度显示
 *
 * @author : Yvon
 * @since : 2022-06-10
 */
@RestController
public class ProDisplayController {

    private static final Map<String, DealThread> threadMap = new ConcurrentHashMap<>();

    @PostMapping("/uploadFile")
    public ResponseData uploadFile(MultipartFile file) {
        return ResponseData.success(dealFile(file));
    }

    @GetMapping("/getDealPercent/{dealId}")
    public ResponseData getDealPercent(@PathVariable("dealId") String dealId) {
        DealThread dealThread = threadMap.get(dealId);
        if (dealThread == null) {
            return ResponseData.failed("处理已结束");
        }
        return ResponseData.success(dealThread.getDealPercent());
    }

    private String dealFile(MultipartFile file) {
        String id = UUID.randomUUID().toString();
        DealThread dealThread = new DealThread(id, file);
        Thread thread = new Thread(dealThread);
        removeMap();
        threadMap.put(id, dealThread);
        thread.start();
        return id;
    }

    /**
     * 及时清理Map，防止OOM
     *
     * @return void
     * @author : Yvon / 2022-06-10
     */
    private void removeMap() {
        if (CollUtil.isNotEmpty(threadMap)) {
            threadMap.keySet().forEach(key -> {
                DealThread dealThread = threadMap.get(key);
                if (dealThread.isFinished()) {
                    threadMap.remove(key);
                }
            });
        }
    }

    private class DealThread implements Runnable {
        private String dealId;

        private MultipartFile file;

        private final int MAX_ROW_NUM;

        private int currentNum;


        private DealThread(String dealId, MultipartFile file) {
            this.dealId = dealId;
            this.file = file;
            MAX_ROW_NUM = 10;
        }


        /**
         * 获取处理进度
         *
         * @return double
         * @author : Yvon / 2022-06-10
         */
        public double getDealPercent() {
            return currentNum * 1.0 / MAX_ROW_NUM;
        }

        /**
         * 是否完成
         *
         * @return boolean
         * @author : Yvon / 2022-06-10
         */
        public boolean isFinished() {
            return MAX_ROW_NUM <= currentNum;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i ++) {
                try {
                    //休眠3000毫秒，模拟复杂的处理过程
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                currentNum++;
                System.out.println("当前进度："+currentNum+"--"+MAX_ROW_NUM );
            }
            System.out.println("进度已结束");
        }

    }

}
